﻿namespace DotNetUtility.Common
{
    using System;
    /// <summary>
    /// To do basic arithmetic operation for instance, Add, Multiply etc.
    /// </summary>
    public static class ArithmeticOperation
    {
        /// <summary>
        /// It will do the addition between given parameters.
        /// </summary>
        /// <typeparam name="T">Define the parameter types.</typeparam>
        /// <param name="sequenceOfTValues">Sequence of values on which addition operation will apply.</param>
        /// <returns>The sum of the sequence of values.</returns>
        /// <example>
        ///     <code>
        ///         bool resultOfAddition = LogicalOperation.DoSequenceOfPlus<int>(4, 3,4,3,4,3);
        ///     </code>
        /// </example>
        /// Contributed by Mohammad Rahman
        public static T DoSequenceOfPlus<T>(params T[] sequenceOfTValues)
            where T : struct
        {
            T additionResult = default(T);
            Func<T, T, T> adder = ExpressionGenerator.AdditionExpression<T>();

            Array.ForEach(sequenceOfTValues,
                (item) =>
                {
                    additionResult = adder(item, additionResult);
                });

            return additionResult;
        }

        /// <summary>
        /// It will do the Multiplication between given parameters.
        /// </summary>
        /// <typeparam name="T">Define the parameter types.</typeparam>
        /// <param name="sequenceOfTValues">Sequence of values on which Multiplication operation will apply.</param>
        /// <returns>The Multiplication of the sequence of values</returns>
        /// <example>
        ///     <code>
        ///         bool resultOfMultiplication = LogicalOperation.DoSequenceOfMultiply<int>(4, 4,4,4);
        ///     </code>
        /// </example>
        /// Contributed by Mohammad Rahman
        public static T DoSequenceOfMultiply<T>(params T[] sequenceOfTValues)
            where T : struct
        {
            dynamic multiplicationResult = (DoSequenceOfPlus<int>(default(int), 1));
            Func<T, T, T> multiplier = ExpressionGenerator.MultiplicationExpression<T>();

            Array.ForEach(sequenceOfTValues,
                (item) =>
                {
                    multiplicationResult = multiplier(item, multiplicationResult);
                });

            return multiplicationResult;
        }
    }
}
